package com.qf.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.*;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import com.qf.common.ShopException;

import javax.swing.undo.AbstractUndoableEdit;
import java.util.Calendar;
import java.util.Map;
import java.util.Set;

public class JWTUitls {

    private static String sing = "2008-shop";

    /**
     * @param param 生成token揉入的用户数据
     * @param exp   过期时间，单位按照秒
     * @return token字符串
     */
    public static String createToken(Map<String, String> param, int exp) {

        JWTCreator.Builder builder = JWT.create();

        // 1.设置超时的时单位是秒
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, exp);
        builder.withExpiresAt(instance.getTime());

        // 2.设置负载(用户的数据)
        Set<Map.Entry<String, String>> entries = param.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            builder.withClaim(entry.getKey(), entry.getValue());
        }

        // 3.设置签名
        return builder.sign(Algorithm.HMAC256(sing));
    }

    // 校验token
    public static DecodedJWT checkToken(String token) throws ShopException {

        // 1.设置签名算法
        Verification require = JWT.require(Algorithm.HMAC256(sing));

        // 2.校验
        try {
            return require.build().verify(token);
        } catch (AlgorithmMismatchException e) {
            throw new ShopException(1001, "签名算法不一致");
        } catch (InvalidClaimException e) {
            throw new ShopException(1002, "负载的数据有误");
        } catch (TokenExpiredException e) {
            throw new ShopException(1003, "token已经过期");
        } catch (SignatureVerificationException e) {
            throw new ShopException(1004, "签名不一致");
        }catch (JWTVerificationException e){
            throw new ShopException(1004, "token校验失败");
        }
    }

    // 验证通过以后从token中获取数据
    public static String getWithClaim(DecodedJWT decodedJWT, String key) {
        return decodedJWT.getClaim(key).asString();
    }
}